#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
#include <cstdio>
#include <cstdlib>
using std::cout;
using std::endl;
using std::cin;

namespace topic
{
	//选择题 题目+ABCD+答案 五行
	//填空题 题目+答案 两行
	//判断题 题目+答案 两行
	class exam 
	{
	public:

		exam()
			:vvvs(std::vector<std::vector<std::vector<std::string>>>(3))
			,vv(std::vector<std::vector<int>>(3))
		{
			MCQ();
			FITB();
			JQ();
		}

		void Printvv() //打印错题
		{
			cout << "***" << examtype[0] << "***" << endl << endl;

			if (vv[0].size() != 0)
			{
				for (const auto& x : vv[0])
				{
					for (int i = 0; i < 6; ++i)
					{
						if (i == 5) cout << "答案:";
						cout << vvvs[0][x][i];
					}
					cout << endl;
				}
			}
			cout << "————————————————————————————————————————————————————————————" << endl;
			cout << endl << "***" << examtype[1] << "***" << endl << endl;

			if (vv[1].size() != 0)
			{
				for (const auto& x : vv[1])
				{
					cout << vvvs[1][x][0];
					cout << "答案:" << vvvs[1][x][1] << endl;
				}
				cout << endl;

			}
			cout << "————————————————————————————————————————————————————————————" << endl;
			cout << endl << "***" << examtype[2] << "***" << endl << endl;

			if (vv[2].size() != 0)
			{
				for (const auto& x : vv[2])
				{
					cout << vvvs[2][x][0];
					cout << "答案:" << vvvs[2][x][1] << endl;
				}
				cout << endl;

			}
		}

		void MCQ() //选择题读取
		{
			FILE* fp = fopen("./MG/MCQ.fdata", "r");
			if (!fp) exit(-1);
			char buf[256] = { 0 };
			int num = 0;
			while (true)
			{
				vvvs[0].push_back(std::vector<std::string>());
				char* ast = nullptr;
				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[0][num].push_back(ast); //题目

				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[0][num].push_back(ast); //A

				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[0][num].push_back(ast); //B

				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[0][num].push_back(ast); //C

				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[0][num].push_back(ast); //D

				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[0][num].push_back(ast); //答案

				++num;
			}
			fclose(fp);
			while (vvvs[0].back().size() == 0) vvvs[0].pop_back();
		}

		void FITB() //填空题读取
		{
			FILE* fp = fopen("./MG/FITB.fdata", "r");
			if (!fp) exit(-1);
			char buf[256] = { 0 };
			int num = 0;
			while (true)
			{
				vvvs[1].push_back(std::vector<std::string>());
				char* ast = nullptr;
				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[1][num].push_back(ast); //题目

				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[1][num].push_back(ast); //答案

				++num;
			}
			fclose(fp);
			while (vvvs[1].back().size() == 0) vvvs[1].pop_back();
		}

		void JQ()	//判断题读取
		{
			FILE* fp = fopen("./MG/JQ.fdata", "r");
			if (!fp) exit(-1);
			char buf[256] = { 0 };
			int num = 0;
			while (true)
			{
				vvvs[2].push_back(std::vector<std::string>());
				char* ast = nullptr;
				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[2][num].push_back(ast); //题目

				ast = fgets(buf, 256, fp);
				if (!ast) break;
				vvvs[2][num].push_back(ast); //答案

				++num;
			}
			fclose(fp);

			while (vvvs[2].back().size() == 0) vvvs[2].pop_back();
		}

		void WQ(size_t i, size_t k) //记录错题
		{
			for (const auto& x : vv[i]) //检查是否是重复错题
				if (x == k) return;

			vv[i].push_back(k); //记录错题
		}

		void DTQ(size_t i, size_t k) //做题函数 题目类型 题目号
		{
			cout << "*" << examtype[i] << "*" << endl << endl; //题目类型
			for (int j = 0; j < vvvs[i][k].size() - 1; ++j) cout << vvvs[i][k][j]; //打印题目

			std::string answer; //记录答案
			if (i == 0)
			{
				cout << "请输入选项：";
				cin >> answer;
				if (answer[0] >= 97) answer[0] -= 32;
			}
			else if (i == 1)
			{
				cout << "请输入答案：";
				cin >> answer;
			}
			else if (i == 2)
			{
				cout << "请输入判断(T正确/F错误)：";
				cin >> answer;
				if (answer[0] >= 97) answer[0] -= 32;
			}
			answer.push_back('\n');
			if (answer == vvvs[i][k][vvvs[i][k].size() - 1])
			{
				cout << "回答正确！" << endl << endl;
			}
			else
			{
				cout << "回答错误！" << "  正确答案：" << vvvs[i][k][vvvs[i][k].size() - 1] << endl;
				WQ(i, k);
			}
		}

		void All_Random() //三个类型题目随机抽题做
		{
			srand(time(nullptr));
			while (true)
			{
				int i = rand() % 3; //随机做题类型
				if (i > 3) exit(-3);
				int k = rand() % vvvs[i].size(); //第几题
				if (k > vvvs[i].size()) exit(-3);
				DTQ(i,k);
				cout << "回车Enter进入下一题(输入0退出)> ";
				getchar();
				if (getchar() == '0') break;
				system("cls"); //刷新屏幕
			}
		}

		void exam_mcq() //只做选择
		{
			srand(time(nullptr));
			while (true)
			{
				int k = rand() % vvvs[0].size(); //第几题
				if (k > vvvs[0].size()) exit(-3);
				DTQ(0, k);
				cout << "回车Enter进入下一题(输入0退出)> ";
				getchar();
				if (getchar() == '0') break;
				system("cls"); //刷新屏幕
			}
		}

		void exam_fitb() //只做填空
		{
			srand(time(nullptr));
			while (true)
			{
				int k = rand() % vvvs[1].size(); //第几题
				if (k > vvvs[1].size()) exit(-3);
				DTQ(1, k);
				cout << "回车Enter进入下一题(输入0退出)> ";
				getchar();
				if (getchar() == '0') break;
				system("cls"); //刷新屏幕
			}
		}

		void exam_jq() //只做填空
		{
			srand(time(nullptr));
			while (true)
			{
				int k = rand() % vvvs[2].size(); //第几题
				if (k > vvvs[2].size()) exit(-3);
				DTQ(2, k);
				cout << "回车Enter进入下一题(输入0退出)> ";
				getchar();
				if (getchar() == '0') break;
				system("cls"); //刷新屏幕
			}
		}

		size_t size0() const { return vvvs[0].size(); }
		size_t size1() const { return vvvs[1].size(); }
		size_t size2() const { return vvvs[2].size(); }

		void PrintSize()
		{
			cout << "当前题库情况:" << endl;
			cout << "选择题:" << size0() << "道" << endl;
			cout << "填空题:" << size1() << "道" << endl;
			cout << "判断题:" << size2() << "道" << endl;
			cout << "一共:" << size0()+size1()+size2() << "道" << endl;
			cout << endl;
		}
	private:
		//题型-第几题-内容(选择题5行 判断题和填空题2行)
		std::vector<std::vector<std::vector<std::string>>> vvvs;
		const char* examtype[3] = { "选择题","填空题","判断题" };
		std::vector<std::vector<int>> vv; //错题集
	};
	
}